package com.rjkj.medicalwaste.database

import android.content.Context
import androidx.lifecycle.LiveData
import androidx.paging.PagingSource
import androidx.room.*
import com.rjkj.medicalwaste.bean.*

@Dao
interface UserDao {
    //更新上传状态
    @Query("UPDATE garbage SET uploadState =:state WHERE garbageQRCode =:garbageQRCode")
    suspend fun updateState(garbageQRCode: String, state: Int)

    //获取上传状态
    @Query("SELECT * FROM garbage where hospitalId =:hospitalId AND uploadState >= 0x0000 AND uploadState <= 0x0001")
    suspend fun findUpdateState1(hospitalId: String): List<GarbageBean>

    @Query("SELECT * FROM garbage where hospitalId =:hospitalId AND uploadState >= 0x0001 AND uploadState < 0x0100")
    suspend fun findUpdateState2(hospitalId: String): List<GarbageBean>

    @Query("SELECT * FROM garbage where hospitalId =:hospitalId AND uploadState >= 0x0010 AND uploadState <0x1000")
    suspend fun findUpdateState3(hospitalId: String): List<GarbageBean>

    @Query("SELECT * FROM garbage where hospitalId =:hospitalId AND uploadState >= 0x1000 AND uploadState <0x1111")
    suspend fun findUpdateState4(hospitalId: String): List<GarbageBean>

    @Insert
    suspend fun insertUser(user: UserBean): Long

    @Insert
    suspend fun insertUserList(user: List<UserBean>): List<Long>

    //删除全部
    @Query("DELETE FROM user")
    suspend fun deleteAllUser()

    //使用LiveData就不需要用挂起suspend
    @Query("SELECT * FROM user WHERE qrcode=:qrcode")
    fun getUserByCode(qrcode: String): LiveData<UserBean>
    //使用LiveData就不需要用挂起suspend

    @Query("SELECT * FROM user WHERE qrcode=:qrcode")
    suspend fun getUserByCode2(qrcode: String): UserBean?

    // 配合LiveData 返回所有的鞋子
    @Query("SELECT * FROM user")
    fun getAllUser(): PagingSource<Int, UserBean>


    @Query("SELECT * FROM user WHERE roleId =:roleId")
    fun findUserByRoleId(roleId: String): PagingSource<Int, UserBean>
}

data class GarbageRequestOutbound(
    val id: Int,
    val garbageBoxQRCode: String,
    val garbageUserStatus: String = GarbageStatus.finished
)

data class GarbageRequestCodeAndState(
    val id: Int,
    val garbageBoxQRCode: String,
    val garbageUserStatus: String,
    val tempBoxQRCode: String = ""
)

data class GarbageRequestTempCode(
    val id: Int,
    val tempBoxQRCode: String,
    val garbageUserStatus: String,
    val reviewWeightState: String,
    val reviewWeight: String,
    val garbageBoxQRCode: String = ""
)

data class GarbageRequestOpenBoxAddGarbage(
    val id: Int,
    val garbageBoxQRCode: String,
    val garbageUserStatus: String,
    val garbageWeight: String,
    val reviewWeightState: String,
    val reviewTime: String
)


data class GarbageRequestUnReview(
    @ColumnInfo(name = "id") val id: Int,
    @ColumnInfo(name = "hospitalId") val hospitalId: String,
    @ColumnInfo(name = "garbageQRCode") val garbageQRCode: String,
    @ColumnInfo(name = "garbageUserStatus") val garbageUserStatus: String,
    @ColumnInfo(name = "reviewWeightState") val reviewWeightState: String,
    @ColumnInfo(name = "garbageType") val garbageType: String, //垃圾类型
    @ColumnInfo(name = "departmentName") val departmentName: String, //科室名字
    @ColumnInfo(name = "garbageWeight") val garbageWeight: String, //垃圾重量
    @ColumnInfo(name = "garbageTime") val garbageTime: String,  //垃圾回收时间
)

data class GarbageSetUnReview(
    val id: Int,
    val garbageQRCode: String,
    val garbageUserStatus: String,
    val reviewWeightState: String,
    val tempBoxQRCode: String = "",
    val reviewDeviceSN: String = "",
    val reviewWeight: String = "",
    val reviewType: String = "0",
    val reviewTime: String = "0000-00-00 00:00:00",
)

data class GarbageSetBoxed(
    val id: Int,
    val garbageQRCode: String,
    val garbageUserStatus: String,
    val tempBoxQRCode: String = "",
    val garbageBoxQRCode: String = "",
    val garbageBoxDeviceSN: String = "",
    val garbageBoxPosition: String = "0",
    val garbageBoxType: String = "",
    val garbageBoxWeight: String = "",
    val garbageCNT: Int = 0,
    val garbageBoxStatus: String = "0",
    val garbageBoxChangePlace: String = "0",
    val garbageBoxChangeTime: String = "0000-00-00 00:00:00",
    val garbageBoxTime: String = "0000-00-00 00:00:00",
    val boxCleanerQRCode: String = "",
)

data class GarbageSetReviewAndBoxed(
    val id: Int,
    val garbageQRCode: String,
    val garbageUserStatus: String,
    val tempBoxQRCode: String = "",
    val garbageBoxQRCode: String = "",
    val garbageBoxDeviceSN: String = "",
    val garbageBoxPosition: String = "0",
    val garbageBoxType: String = "",
    val garbageBoxWeight: String = "",
    val garbageCNT: Int = 0,
    val garbageBoxStatus: String = "0",
    val garbageBoxChangePlace: String = "0",
    val garbageBoxChangeTime: String = "0000-00-00 00:00:00",
    val garbageBoxTime: String = "0000-00-00 00:00:00",
    val reviewWeightState: String,
    val reviewDeviceSN: String = "",
    val reviewWeight: String = "",
    val reviewType: String = "",
    val reviewTime: String = "0000-00-00 00:00:00",
)
data class GarbageSetReviewAndBoxedAddUser(
    val id: Int,
    val garbageQRCode: String,
    val garbageUserStatus: String,
    val tempBoxQRCode: String = "",
    val garbageBoxQRCode: String = "",
    val garbageBoxDeviceSN: String = "",
    val garbageBoxPosition: String = "0",
    val garbageBoxType: String = "",
    val garbageBoxWeight: String = "",
    val garbageCNT: Int = 0,
    val garbageBoxStatus: String = "0",
    val garbageBoxChangePlace: String = "0",
    val garbageBoxChangeTime: String = "0000-00-00 00:00:00",
    val garbageBoxTime: String = "0000-00-00 00:00:00",
    val reviewWeightState: String,
    val reviewDeviceSN: String = "",
    val reviewWeight: String = "",
    val reviewType: String = "",
    val reviewTime: String = "0000-00-00 00:00:00",
    val reviewCleanerQRCode: String,
    val boxCleanerQRCode:String,
    val reviewStorageQRCode:String,
)
data class GarbageSetStorage(
    val id: Int,
    val garbageQRCode: String,
    val garbageUserStatus: String = GarbageStatus.loading,
    val storageTime: String,
    val reviewStorageQRCode: String,
    val reviewDeviceSN: String,
    val reviewWeight: String,
    val reviewType: String = "0",
    val reviewTime: String,
    val reviewCleanerQRCode: String
)

data class GarbageSetOutbound(
    val id: Int,
    val garbageQRCode: String,
    val garbageUserStatus: String,
    val handoverDeviceSN: String,
    val handoverQRCode: String,
    val handoverCleanerQRCode: String,
    val handoverTime: String,
)

data class GarbageBaseInfo(
    @ColumnInfo(name = "id") val id: Int,
    @ColumnInfo(name = "garbageQRCode") val garbageQRCode: String,
    @ColumnInfo(name = "garbageUserStatus") val garbageUserStatus: String,
    @ColumnInfo(name = "garbageType") val garbageType: String,
    @ColumnInfo(name = "garbageWeight") val garbageWeight: String,
    val departmentName: String, //科室名字
    val nurseQRName: String, //医护人员名字
    val departmentQRCode: String, //科室二维码
    val nurseQRCode: String, //医护人员二维码
)


data class GarbageReviewWeightDialogInfo(
    @ColumnInfo(name = "id") val id: Int,
    @ColumnInfo(name = "garbageQRCode") val garbageQRCode: String,
    @ColumnInfo(name = "garbageUserStatus") val garbageUserStatus: String,
    @ColumnInfo(name = "garbageType") val garbageType: String,
    @ColumnInfo(name = "garbageWeight") val garbageWeight: String,
    @ColumnInfo(name = "hospitalId") val hospitalId: String, //医院ID
    @ColumnInfo(name = "hospitalName") val hospitalName: String, //医院名字
    @ColumnInfo(name = "cleanerName") val cleanerName: String, //清理工名字
    @ColumnInfo(name = "departmentName") val departmentName: String, //科室名字
    @ColumnInfo(name = "nurseQRName") val nurseQRName: String, //医护人员名字
    @ColumnInfo(name = "departmentQRCode") val departmentQRCode: String, //科室二维码
    @ColumnInfo(name = "nurseQRCode") val nurseQRCode: String, //医护人员二维码
    @ColumnInfo(name = "cleanerQRCode") val cleanerQRCode: String, //收集阶段清理工二维码
    @ColumnInfo(name = "garbageBoxWeight") val garbageBoxWeight: String,//所有装箱医废的总重
    @ColumnInfo(name = "garbageBoxQRCode") val garbageBoxQRCode: String,//所有装箱医废的总重
    @ColumnInfo(name = "garbageCNT") val garbageCNT: Int,//装箱袋数
    @ColumnInfo(name = "garbageBoxTime") val garbageBoxTime: String,//箱子状态变更时间
)

data class GarbageInTempBoxInfo(
    @ColumnInfo(name = "id") val id: Int,
    @ColumnInfo(name = "garbageQRCode") val garbageQRCode: String,
    @ColumnInfo(name = "garbageUserStatus") val garbageUserStatus: String,
    @ColumnInfo(name = "garbageType") val garbageType: String,
    @ColumnInfo(name = "garbageWeight") val garbageWeight: String,
    @ColumnInfo(name = "tempBoxQRCode") val tempBoxQRCode: String,
)

data class GarbageInBoxInfo(
    @ColumnInfo(name = "id") val id: Int,
    @ColumnInfo(name = "garbageQRCode") val garbageQRCode: String,
    @ColumnInfo(name = "garbageUserStatus") val garbageUserStatus: String,
    @ColumnInfo(name = "garbageType") val garbageType: String,
    @ColumnInfo(name = "garbageBoxTime") val garbageBoxTime: String,
    @ColumnInfo(name = "garbageBoxQRCode") val garbageBoxQRCode: String,
    @ColumnInfo(name = "garbageBoxWeight") val garbageBoxWeight: String,
    @ColumnInfo(name = "garbageWeight") val garbageWeight: String,
)

data class BoxInfo(
    @ColumnInfo(name = "id") val id: Int,
    @ColumnInfo(name = "garbageQRCode") val garbageQRCode: String,
    @ColumnInfo(name = "garbageBoxQRCode") val garbageBoxQRCode: String,
)

@Dao
interface GarbageDao {


    //检查箱子是否存在
    @Query("SELECT id,garbageQRCode,garbageBoxQRCode FROM garbage WHERE garbageBoxQRCode =:garbageBoxQRCode ")
    suspend fun findBoxByBoxCode(garbageBoxQRCode: String): List<BoxInfo>

    //获取所有未复核的医废袋
    @Query("SELECT id,hospitalId,garbageQRCode,garbageUserStatus,reviewWeightState,garbageType,departmentName,garbageWeight,garbageTime FROM garbage WHERE hospitalId =:hospitalId AND reviewStorageQRCode =:reviewStorageQRCode AND garbageUserStatus in(:garbageUserStatus)  ORDER BY garbageTime DESC")
    fun getAllGarbageRequestUnReview(
        hospitalId: String,
        reviewStorageQRCode: String,
        garbageUserStatus: List<String> = listOf(
            GarbageStatus.loading,
            GarbageStatus.review
        )
    ): PagingSource<Int, GarbageRequestUnReview>

    @Query("SELECT id,hospitalId,garbageQRCode,garbageUserStatus,reviewWeightState,garbageType,departmentName,garbageWeight,garbageTime FROM garbage WHERE hospitalId =:hospitalId AND reviewStorageQRCode =:reviewStorageQRCode AND garbageUserStatus in(:garbageUserStatus)  ORDER BY garbageTime DESC")
    suspend fun getAllGarbageRequestUnReview2(
        hospitalId: String,
        reviewStorageQRCode: String,
        garbageUserStatus: List<String> = listOf(
            GarbageStatus.loading,
            GarbageStatus.review
        )
    ): List<GarbageRequestUnReview>
    //复核医废袋更新数据
    @Update(entity = GarbageBean::class)
    suspend fun updateGarbageSetUnReview(vararg garbageSetUnReview: GarbageSetUnReview): Int

    //装箱医废袋更新数据
    @Update(entity = GarbageBean::class)
    suspend fun updateGarbageSetBoxed(vararg garbageSetUnReview: GarbageSetBoxed): Int

    //复核+装箱医废袋更新数据
    @Update(entity = GarbageBean::class)
    suspend fun updateGarbageSetReviewAndBoxed(garbageSetReviewAndBoxed: GarbageSetReviewAndBoxed): Int

    //复核+装箱医废袋更新数据
    @Update(entity = GarbageBean::class)
    suspend fun updateGarbageSetReviewAndBoxedList(garbageSetReviewAndBoxedList: List<GarbageSetReviewAndBoxed>)
    //复核+装箱医废袋更新数据
    @Update(entity = GarbageBean::class)
    suspend fun updateGarbageSetReviewAndBoxedAddUserList(garbageSetReviewAndBoxedList: List<GarbageSetReviewAndBoxedAddUser>)
    //出库医废袋更新数据
    @Update(entity = GarbageBean::class)
    suspend fun updateGarbageSetOutbound(garbageSetOutbound: List<GarbageSetOutbound>)

    //box添加或删除要将所有的box内的医废信息更新
    @Query("UPDATE garbage SET garbageBoxWeight =:garbageBoxWeight,garbageCNT = :garbageCNT,garbageBoxTime = :garbageBoxTime where garbageBoxQRCode =:garbageBoxQRCode")
    fun updateChangeGarbageFromBox(
        garbageBoxQRCode: String,
        garbageBoxWeight: String,
        garbageCNT: Int,
        garbageBoxTime: String
    )

    //入库医废袋更新数据
    @Update(entity = GarbageBean::class)
    suspend fun updateGarbageSetStorage2(garbageSetStorage: List<GarbageSetStorage>): Int

    //入库医废袋更新数据
    @Query("UPDATE garbage SET garbageUserStatus =:changeGarbageStatus,reviewStorageQRCode = :reviewStorageQRCode where hospitalId =:hospitalId AND garbageUserStatus =:primaryGarbageStatus")
    suspend fun updateGarbageSetStorage(
        hospitalId: String,
        reviewStorageQRCode: String,
        primaryGarbageStatus: String = GarbageStatus.collect,
        changeGarbageStatus: String = GarbageStatus.loading
    ): Int

    //TODO 未添加查询条件
    @Query("SELECT id,garbageQRCode,garbageUserStatus,hospitalId,hospitalName,garbageType,garbageWeight,cleanerName,departmentName,nurseQRName,departmentQRCode,nurseQRCode,cleanerQRCode,garbageBoxWeight,garbageCNT,garbageBoxTime,garbageBoxQRCode FROM garbage WHERE garbageQRCode =:code")
    fun findGarbageReviewWeightDialogInfoByCode(code: String): LiveData<GarbageReviewWeightDialogInfo>
    @Query("SELECT id,garbageQRCode,garbageUserStatus,hospitalId,hospitalName,garbageType,garbageWeight,cleanerName,departmentName,nurseQRName,departmentQRCode,nurseQRCode,cleanerQRCode,garbageBoxWeight,garbageCNT,garbageBoxTime,garbageBoxQRCode FROM garbage WHERE garbageQRCode =:code")
    suspend fun findGarbageReviewWeightDialogInfoByCode2(code: String): GarbageReviewWeightDialogInfo?
    //获取在临时箱子内的医废
    @Query("SELECT id,garbageQRCode,garbageUserStatus,garbageType,garbageWeight,tempBoxQRCode FROM garbage WHERE hospitalId =:hospitalId AND reviewStorageQRCode = :storeRoomCode  AND garbageUserStatus =:state AND tempBoxQRCode !=:tempBoxQRCode")
    fun getTempBoxGarbageBeanList(
        hospitalId: String,
        storeRoomCode: String,
        state: String = GarbageStatus.review,
        tempBoxQRCode: String = ""
    ): LiveData<List<GarbageInTempBoxInfo>>

    //获取在正常箱子内的医废
    @Query("SELECT id,garbageQRCode,garbageUserStatus,garbageType,garbageBoxTime,garbageBoxQRCode,garbageBoxWeight,garbageWeight FROM garbage WHERE hospitalId =:hospitalId AND reviewStorageQRCode = :storeRoomCode AND  garbageUserStatus =:state AND garbageBoxQRCode !=:garbageBoxQRCode")
    fun getBoxGarbageBeanList(
        hospitalId: String,
        storeRoomCode: String,
        state: String = GarbageStatus.boxed,
        garbageBoxQRCode: String = ""
    ): LiveData<List<GarbageInBoxInfo>>

    @Query("SELECT id,garbageQRCode,garbageUserStatus,garbageType,garbageBoxTime,garbageBoxQRCode,garbageBoxWeight,garbageWeight FROM garbage WHERE hospitalId =:hospitalId AND garbageUserStatus =:state AND garbageBoxQRCode =:garbageBoxQRCode")
    suspend fun getBoxGarbageBean(
        hospitalId: String,
        state: String = GarbageStatus.boxed,
        garbageBoxQRCode: String
    ): List<GarbageInBoxInfo>


    @Query("SELECT * FROM garbage WHERE hospitalId =:hospitalId AND garbageUserStatus =:garbageUserStatus  ORDER BY garbageTime DESC")
    fun getAllCollectGarbage(
        hospitalId: String,
        garbageUserStatus: String = GarbageStatus.collect
    ): PagingSource<Int, GarbageBean>


    @Query("SELECT * FROM garbage WHERE garbageBoxQRCode =:garbageBoxQRCode AND garbageUserStatus =:garbageUserStatus  ORDER BY garbageTime DESC")
    fun getOpenBoxGarbage(
        garbageBoxQRCode: String,
        garbageUserStatus: String = GarbageStatus.boxed
    ): PagingSource<Int, GarbageBean>

    @Update
    suspend fun updateGarbageBean(garbageBean: GarbageBean): Int

    @Update(entity = GarbageBean::class)
    suspend fun updateOpenBoxAddGarbage(garbageRequestCodeAndState: GarbageRequestOpenBoxAddGarbage): Int

    @Update(entity = GarbageBean::class)
    suspend fun updateGarbageBeanState(list: List<GarbageRequestOutbound>)

    @Update(entity = GarbageBean::class)
    suspend fun updateGarbageBeanCode(garbageRequestCodeAndState: GarbageRequestCodeAndState): Int

    @Update(entity = GarbageBean::class)
    suspend fun updateGarbageBeanCodeList(garbageRequestCodeAndState: List<GarbageRequestCodeAndState>): Int

    @Update(entity = GarbageBean::class)
    suspend fun updateGarbageBeanTempCode(garbageRequestTempCode: GarbageRequestTempCode): Int

    @Query("SELECT * FROM garbage WHERE hospitalId =:hospitalId AND garbageUserStatus IN (:states) ORDER BY garbageUserStatus ASC,garbageTime DESC")
    fun getMultiStateGarbageToPaging(
        hospitalId: String,
        states: Array<String>
    ): PagingSource<Int, GarbageBean>

    @Query("SELECT * FROM garbage WHERE hospitalId =:hospitalId AND garbageUserStatus IN (:states) ORDER BY garbageUserStatus ASC,garbageTime DESC")
    fun getMultiStateGarbageToList(
        hospitalId: String,
        states: Array<String>
    ): LiveData<List<GarbageBean>>

    @Query("SELECT * FROM garbage WHERE hospitalId =:hospitalId AND reviewStorageQRCode = :reviewStorageQRCode AND garbageUserStatus IN (:states) ORDER BY garbageUserStatus ASC,garbageTime DESC")
    suspend fun getMultiStateGarbageToList2(
        hospitalId: String,
        reviewStorageQRCode: String,
        states: Array<String>
    ): List<GarbageBean>

    @Query("SELECT * FROM garbage WHERE hospitalId =:hospitalId AND garbageUserStatus =:state ORDER BY garbageTime DESC")
    fun getStateGarbageToPaging(hospitalId: String, state: String): PagingSource<Int, GarbageBean>

    @Query("SELECT * FROM garbage WHERE hospitalId =:hospitalId AND garbageUserStatus =:state ORDER BY garbageTime DESC")
    fun getStateGarbageToList(hospitalId: String, state: String): LiveData<List<GarbageBean>>

    @Query("SELECT * FROM garbage WHERE hospitalId =:hospitalId AND garbageUserStatus =:state ORDER BY garbageTime DESC")
    suspend fun getStateGarbage(hospitalId: String, state: String): List<GarbageBean>

    @Query("SELECT * FROM garbage WHERE hospitalId =:hospitalId AND garbageUserStatus =:state AND reviewStorageQRCode =:reviewStorageQRCode  ORDER BY garbageTime DESC")
    fun getStateGarbageByStoreCodeToList(
        hospitalId: String,
        state: String,
        reviewStorageQRCode: String
    ): LiveData<List<GarbageBean>>

    @Query("SELECT * FROM garbage WHERE garbageQRCode =:code")
    fun findGarbageByCode(code: String): LiveData<GarbageBean>

    @Query("SELECT * FROM garbage WHERE garbageQRCode =:code")
    suspend fun findGarbageByCode2(code: String): GarbageBean?
    @Query("SELECT * FROM garbage WHERE garbageBoxTime =:time")
    suspend fun findGarbageByBoxTime(time: String): List<GarbageBean>
    @Query("SELECT * FROM garbage WHERE garbageBoxQRCode =:code")
    suspend fun findGarbageByBoxCode(code: String): List<GarbageBean>

    data class QueryGarbageRequestCodeAndState(
        @ColumnInfo(name = "id") val id: Int,
        @ColumnInfo(name = "garbageQRCode") val garbageQRCode: String = "",
        @ColumnInfo(name = "garbageUserStatus") val garbageUserStatus: String = "",
    )

    @Query("SELECT id,garbageQRCode,garbageUserStatus FROM garbage WHERE garbageQRCode =:garbageQRCode AND garbageUserStatus =:garbageUserStatus")
    suspend fun findGarbageByCodeAndStatus(
        garbageQRCode: String,
        garbageUserStatus: String = GarbageStatus.collect
    ): QueryGarbageRequestCodeAndState?

    @Query("SELECT id,garbageQRCode,garbageUserStatus FROM garbage WHERE garbageQRCode =:garbageQRCode AND garbageUserStatus in(:garbageUserStatus) AND garbageType=:garbageType")
    suspend fun findGarbageByCodeAndStatusAndType(
        garbageQRCode: String,
        vararg garbageUserStatus: String,
        garbageType: String
    ): QueryGarbageRequestCodeAndState?

    @Insert(onConflict = OnConflictStrategy.ABORT)
    suspend fun insertGarbage(garbageBean: GarbageBean): Long

    @Insert(onConflict = OnConflictStrategy.ABORT)
    suspend fun insertGarbageList(garbageBeanList: List<GarbageBean>)

    @Delete
    suspend fun deleteGarbage(garbageBean: GarbageBean)

    @Query("DELETE FROM garbage WHERE garbageBoxQRCode =:garbageQRCode")
    suspend fun deleteGarbageByCode(garbageQRCode:String)

    @Query("DELETE FROM garbage")
    suspend fun deleteAllGarbage()

    @Query("SELECT * FROM garbage WHERE reviewStorageQRCode =:roomId AND hospitalId =:hospitalId AND garbageUserStatus =:garbageUserStatus")
    fun findAllGarbageBoxedByRH(
        roomId: String,
        hospitalId: String,
        garbageUserStatus: String = GarbageStatus.boxed
    ): LiveData<List<GarbageBean>>
}

@Dao
interface BoxDao {
    /**
     * 根据箱码查询箱子
     * @param garbageBoxQRCode String
     * @return BoxBean
     */
    @Query("SELECT * FROM BoxBean WHERE garbageBoxQRCode =:garbageBoxQRCode")
    suspend fun findBoxByBoxOnlyCode(garbageBoxQRCode: String): BoxBean

    /**
     * 插入一个箱子
     * @param data BoxBean
     */
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insertBoxBeanData(data: BoxBean)

    @Query("SELECT * FROM BoxBean WHERE stagingRoomQRCode=:roomId")
    fun findAllBoxByRoomId(roomId: String): PagingSource<Int, BoxBean>

    @Transaction
    @Query("SELECT * FROM BoxBean WHERE stagingRoomQRCode=:roomId AND garbageCNT > 0 AND garbageBoxStatus = :status")
    fun getBoxWithGarbageList(
        roomId: String,
        status: String = BoxStatus.working
    ): PagingSource<Int, BoxWithGarbage>

    data class TempBoxRequestCount(val id: Int, val tempBoxQRCode: String, val garbageCNT: Int)
    data class BoxRequestCount(val id: Int, val garbageBoxQRCode: String, val garbageCNT: Int)
    data class BoxRequestStatus(
        val id: Int,
        val garbageBoxQRCode: String,
        val garbageBoxStatus: String = GarbageStatus.finished
    )

    @Update(entity = BoxBean::class)
    suspend fun updateBoxOutbound(list: List<BoxRequestStatus>): Int

    @Update(entity = BoxBean::class)
    suspend fun updateBoxCount(tempBoxBean: BoxRequestCount): Int

    @Update(entity = TempBoxBean::class)
    suspend fun updateTempBoxCount(tempBoxBean: TempBoxRequestCount): Int

    @Update
    suspend fun updateTempBox(tempBoxBean: TempBoxBean): Int
    //临时箱子
    /**
     * 根据箱码查询箱子
     * @param code String
     * @return BoxBean
     */
    @Query("SELECT * FROM TempBoxBean WHERE tempBoxQRCode =:code")
    suspend fun findBoxByTempCode(code: String): TempBoxBean

    /**
     * 插入一个临时箱子
     * @param data BoxBean
     */
    @Insert(onConflict = OnConflictStrategy.ABORT)
    suspend fun insertTempBoxData(data: TempBoxBean)


    // TODO: 2021/5/24 添加筛选条件 状态是Loading的箱子 11：30
    @Transaction
    @Query("SELECT * FROM TempBoxBean WHERE stagingRoomQRCode=:roomId  AND garbageCNT > 0")
    fun getTempBoxWithGarbageList(roomId: String): PagingSource<Int, TempBoxWithGarbage>

}


@Database(
    entities = [UserBean::class, GarbageBean::class, BoxBean::class, TempBoxBean::class],
    version = 1,
    exportSchema = false
)
abstract class MainDatabase : RoomDatabase() {
    abstract val userDao: UserDao
    abstract val garbageDao: GarbageDao
    abstract val boxDao: BoxDao
}

private lateinit var INSTANCE: MainDatabase

/**
 * Instantiate a database from a context.
 */
fun getDatabase(context: Context): MainDatabase {
    synchronized(MainDatabase::class) {
        if (!::INSTANCE.isInitialized) {
            INSTANCE = Room
                .databaseBuilder(
                    context.applicationContext,
                    MainDatabase::class.java,
                    "MedicalWaste_db"
                )
                .fallbackToDestructiveMigration()
                .build()
        }
    }
    return INSTANCE
}